home *** CD-ROM | disk | FTP | other *** search
- /*
- * This file is part of the portable Forth environment written in ANSI C.
- * Copyright (C) 1995 Dirk Uwe Zoller
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * This file is version 0.9.13 of 17-July-95
- * Check for the latest version of this package via anonymous ftp at
- * roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-VERSION.tar.gz
- * or sunsite.unc.edu:/pub/languages/forth/pfe-VERSION.tar.gz
- * or ftp.cygnus.com:/pub/forth/pfe-VERSION.tar.gz
- *
- * Please direct any comments via internet to
- * duz@roxi.rz.fht-mannheim.de.
- * Thank You.
- */
- /*
- * shell.c --- os commands for pfe
- * (duz 07May94)
- */
-
- #include "forth.h"
- #include "support.h"
- #include "compiler.h"
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include <fcntl.h>
-
- #include "nonansi.h"
- #include "missing.h"
-
-
- #ifdef HAVE_PID
- Code (getpid) { *--sp = (Cell)getpid (); }
- #endif
-
- #ifdef HAVE_UID
- Code (getuid) { *--sp = (Cell)getuid (); }
- Code (geteuid) { *--sp = (Cell)geteuid (); }
- #endif
-
- #ifdef HAVE_GID
- Code (getgid) { *--sp = (Cell)getgid (); }
- #endif
-
- #ifdef HAVE_UMASK
- Code (umask) { *sp = (Cell)umask (*sp); }
- #endif
-
- Code (home) { strpush (getenv ("HOME")); }
- Code (user) { strpush (getenv ("USER")); }
-
- Code (cwd) { strpush (getcwd (pocket (), PATH_LENGTH)); }
-
- Code (pwd)
- {
- outs (getcwd (pocket (), PATH_LENGTH));
- space_();
- }
-
- static void
- do_one (char *p, int (*syscall) (const char *))
- {
- char name[PATH_LENGTH];
-
- store_filename (p + 1, (Byte)*p, name, sizeof name);
- if (syscall (name))
- file_errorz (name);
- }
-
- #define SHWORD1(X) \
- Code (APPEND (X,_execution)) \
- { \
- do_one ((char *)ip, X); \
- SKIP_STRING; \
- } \
- Code (X) \
- { \
- if (STATE) \
- { \
- compile1 (); \
- alloc_word (' '); \
- } \
- else \
- do_one (word (' '), X); \
- } \
- COMPILES (X, APPEND (X,_execution), \
- SKIPS_STRING, DEFAULT_STYLE)
-
- static void
- do_two (char *p1, char *p2, int (*syscall) (const char *, const char *))
- {
- char nm1[PATH_LENGTH], nm2[PATH_LENGTH];
-
- store_filename (p1 + 1, *(Byte *)p1, nm1, sizeof nm1);
- store_filename (p2 + 1, *(Byte *)p2, nm2, sizeof nm2);
- if (syscall (nm1, nm2))
- file_errorz (nm1);
- }
-
- #define SHWORD2(X) \
- Code (APPEND (X,_execution)) \
- { \
- char *p = (char *)ip; \
- SKIP_STRING; \
- do_two (p, (char *)ip, X); \
- SKIP_STRING; \
- } \
- Code (X) \
- { \
- if (STATE) \
- { \
- compile1 (); \
- alloc_word (' '); \
- alloc_word (' '); \
- } \
- else \
- { \
- char *p = pocket (); \
- strcpy (p, word (' ')); \
- do_two (p, word (' '), X); \
- } \
- } \
- COMPILES (X, APPEND(X,_execution), \
- SKIPS_2STRINGS, DEFAULT_STYLE)
-
- #ifdef S_IRUSR
- #define RWALL (S_IRUSR | S_IWUSR | \
- S_IRGRP | S_IWGRP | \
- S_IROTH | S_IWOTH)
- #define RWXALL (RWALL | S_IXUSR | S_IXGRP | S_IXOTH)
- #else
- #define RWALL 0666
- #define RWXALL 0777
- #endif
-
- static int
- md (const char *s)
- {
- #if defined DOS_FILENAMES && !defined EMX
- /* an assumption: */
- return mkdir (s); /* DOS like systems need no permissions. */
- #else /* Holds for Turbo-C and Watcom-C. */
- return mkdir (s, RWXALL);
- #endif
- }
-
- static int
- touch (const char *s)
- {
- int result;
-
- #ifdef HAVE_ACCESS
- if (access (s, F_OK) == 0)
- return utime (s, NULL);
- #endif
- result = open (s, O_WRONLY | O_CREAT, RWALL);
- if (result < 0)
- return result;
- close (result);
- return 0;
- }
-
- static int
- cp (const char *src, const char *dst)
- {
- return copy (src, dst, LONG_MAX) == -1;
- }
-
- static int
- ls (const char *p)
- {
- cr_();
- return systemf (LSCMD" %s", p);
- }
-
- static int
- ll (const char *p)
- {
- cr_();
- return systemf (LLCMD" %s", p);
- }
-
- /*
- * For the macro SHWORD1 to work, it is required that remove is not a
- * macro. If this system lacks remove() and this is normally fixed by
- * #define remove unlink, then define remove as function here.
- */
- #ifdef remove
- #undef remove
- int remove (const char *name) { return unlink (name); }
- #endif
-
- #ifdef AIX1
- extern int link();
- extern int remove();
- extern int chdir();
- extern int rmdir();
- #endif
-
- SHWORD1(remove);
- SHWORD1(touch);
- SHWORD1(chdir);
- SHWORD1(rmdir);
- SHWORD1(md);
- SHWORD1(ls);
- SHWORD1(ll);
- SHWORD2(move);
- SHWORD2(cp);
- #ifdef HAVE_LINK
- SHWORD2(link);
- #endif
-
- LISTWORDS (shell) =
- {
- #ifdef HAVE_PID
- CO ("$$", getpid),
- #endif
- #ifdef HAVE_UID
- CO ("$UID", getuid),
- CO ("$EUID", geteuid),
- #endif
- #ifdef HAVE_GID
- CO ("$GID", getgid),
- #endif
- #ifdef HAVE_UMASK
- CO ("UMASK", umask),
- #endif
- CO ("$HOME", home),
- CO ("$USER", user),
- CO ("$CWD", cwd),
- CO ("PWD", pwd),
- CS ("RM", remove),
- CS ("TOUCH", touch),
- CS ("CD", chdir),
- CS ("RMDIR", rmdir),
- CS ("MKDIR", md),
- CS ("MV", move),
- CS ("CP", cp),
- #ifdef HAVE_LINK
- CS ("LN", link),
- #endif
- CS ("LL", ll),
- CS ("LS", ls),
- };
- COUNTWORDS (shell, "Shell words");
-